﻿// -----------------------------------------------------------------------
// <copyright file="FourierTransformation.cs" company="Microsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace ImageP
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;
    using MathWorks.MATLAB.NET.Arrays;
    using MathWorks.MATLAB.NET.Utility;
    using System.Data;
    using FourierFin;
    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class FourierTransformation
    {
       //Fourier.FourierTrans ft = new Fourier.FourierTrans();
       
      Normalize norm = new Normalize();
      public int[,] normalizedBufferRed;
      public int[,] normalizedBufferGreen;
      public int[,] normalizedBufferBlue;
      public RGBcolor[,] realImage;
      public FourierT ft = new FourierT();
      public MWArray realF;
      public double[,] realBufferR, realBufferG, realBufferB, imgBufferR, imgBufferG, imgBufferB;
      public int width, height;
      public Bitmap bm;
      public void FrequencyDomain(Bitmap Buffer, int width,int height)
      {

          this.width = width;
          this.height = height;
          normalizedBufferRed = new int[height, width];
          normalizedBufferGreen = new int[height, width];
          normalizedBufferBlue = new int[height, width];
          realImage = new RGBcolor[height, width];
          byte[,] R = new byte[Buffer.Height, Buffer.Width];
          byte[,] G = new byte[Buffer.Height, Buffer.Width];
          byte[,] B = new byte[Buffer.Height, Buffer.Width];
          Color Clr;
          for (int i = 0; i < Buffer.Height; i++)
              for (int j = 0; j < Buffer.Width; j++)
              {
                  Clr = Buffer.GetPixel(j, i);
                  R[i, j] = Clr.R;
                  G[i, j] = Clr.G;
                  B[i, j] = Clr.B;
              }


          MWArray ftsR, ftsG, ftsB;
          ftsR = (MWNumericArray)ft.FreqDomian((MWNumericArray)R);
          ftsG = (MWNumericArray)ft.FreqDomian((MWNumericArray)G);
          ftsB = (MWNumericArray)ft.FreqDomian((MWNumericArray)B);

           realBufferR = (double[,]) ft.getReal(ftsR).ToArray();
          realBufferG = (double[,])ft.getReal(ftsG).ToArray();
          realBufferB = (double[,])ft.getReal(ftsB).ToArray();

          imgBufferR = (double[,])ft.getImag(ftsR).ToArray();
          imgBufferG = (double[,])ft.getImag(ftsG).ToArray();
          imgBufferB = (double[,])ft.getImag(ftsB).ToArray();

          //double[,] realBufferR = (double[,])ftsR.ToArray(MWArrayComponent.Real);
          //double[,] realBufferG = (double[,])ftsG.ToArray(MWArrayComponent.Real);
          //double[,] realBufferB = (double[,])ftsB.ToArray(MWArrayComponent.Real);

          //double[,] imgBufferR = (double[,])ftsR.ToArray(MWArrayComponent.Imaginary);
          //double[,] imgBufferG = (double[,])complexBufferG.ToArray(MWArrayComponent.Imaginary);
          //double[,] imgBufferB = (double[,])complexBufferB.ToArray(MWArrayComponent.Imaginary);

          double[,] magnitudeBufferR = new double[height, width];
          double[,] magnitudeBufferG = new double[height, width];
          double[,] magnitudeBufferB = new double[height, width];

          double[,] logMagnitudeBufferR = new double[height, width];
          double[,] logMagnitudeBufferG = new double[height, width];
          double[,] logMagnitudeBufferB = new double[height, width];

      
          
          for (int i = 0; i < height; i++)
          {
              for (int j = 0; j < width; j++)
              {
                  magnitudeBufferR[i, j] = Math.Sqrt((Math.Pow(Convert.ToDouble(realBufferR[i, j]), 2)) + (Math.Pow(Convert.ToDouble(imgBufferR[i, j]), 2)));
                  magnitudeBufferG[i, j] = Math.Sqrt((Math.Pow(Convert.ToDouble(realBufferG[i, j]), 2)) + (Math.Pow(Convert.ToDouble(imgBufferG[i, j]), 2)));
                  magnitudeBufferB[i, j] = Math.Sqrt((Math.Pow(Convert.ToDouble(realBufferB[i, j]), 2)) + (Math.Pow(Convert.ToDouble(imgBufferB[i, j]), 2)));

                  logMagnitudeBufferR[i, j] = Math.Log(magnitudeBufferR[i, j]+ 0.1);
                  logMagnitudeBufferG[i, j] = Math.Log(magnitudeBufferG[i, j]+ 0.1);
                  logMagnitudeBufferB[i, j] = Math.Log(magnitudeBufferB[i, j]+ 0.1);


              }
          }
          normalizedBufferRed = norm.Normalize_imagefft(logMagnitudeBufferR, height, width);
          normalizedBufferGreen = norm.Normalize_imagefft(logMagnitudeBufferG, height, width);
          normalizedBufferBlue = norm.Normalize_imagefft(logMagnitudeBufferB, height, width);


        
      }
      public Bitmap inverseFreq(Bitmap im, int height,int width)
      {
          byte[,] R = new byte[height, width];
          byte[,] G = new byte[height, width];
          byte[,] B = new byte[height, width];
          Color Clr;
          for (int i = 0; i < height; i++)
              for (int j = 0; j < width; j++)
              {
                  Clr = im.GetPixel(j, i);
                  R[i, j] = Clr.R;
                  G[i, j] = Clr.G;
                  B[i, j] = Clr.B;
              }
          MWArray ftsR, ftsG, ftsB;
          ftsR = (MWArray)ft.FreqDomian((MWNumericArray)R);
          ftsG = (MWNumericArray)ft.FreqDomian((MWNumericArray)G);
          ftsB = (MWNumericArray)ft.FreqDomian((MWNumericArray)B);

          realBufferR = (double[,])ft.getReal(ftsR).ToArray();
          realBufferG = (double[,])ft.getReal(ftsG).ToArray();
          realBufferB = (double[,])ft.getReal(ftsB).ToArray();

          imgBufferR = (double[,])ft.getImag(ftsR).ToArray();
          imgBufferG = (double[,])ft.getImag(ftsG).ToArray();
          imgBufferB = (double[,])ft.getImag(ftsB).ToArray();


          //inverse
          MWArray inverseFreqR, inverseFreqG, inverseFreqB;
          double[,] realR, realG, realB;
          bm = new Bitmap(width, height);
          inverseFreqR = (MWArray)ft.InvF((MWNumericArray)realBufferR, (MWNumericArray)imgBufferR);
          inverseFreqG = (MWArray)ft.InvF((MWNumericArray)realBufferG, (MWNumericArray)imgBufferG);
          inverseFreqB = (MWArray)ft.InvF((MWNumericArray)realBufferB, (MWNumericArray)imgBufferB);
          realR = (double[,])inverseFreqR.ToArray();
          realG = (double[,])inverseFreqG.ToArray();
          realB = (double[,])inverseFreqB.ToArray();
          for (int i = 0; i < height; i++)
          {
              for (int j = 0; j < width; j++)
              {
                  bm.SetPixel(j, i, System.Drawing.Color.FromArgb(Convert.ToInt32(realR[i, j]), Convert.ToInt32(realG[i, j]), Convert.ToInt32(realB[i, j])));
              }
          }

          return bm;
      }
      public int[,] getNormRed()
      {
          return normalizedBufferRed;
      }
      public int[,] getNormGreen()
      {
          return normalizedBufferGreen;
      }
      public int[,] getNormBlue()
      {
          return normalizedBufferBlue;
      }
    }
}
